#include <iostream>
#include <fstream>
#include "Labyrinth.h"
#include "CollDetection.h"

namespace Labyrinth
{
	static GLuint textureId[6];
	struct Character _karakter;

	GLuint loadTexture(Image *image) 
	{
		GLuint textureId;
		glGenTextures(1, &textureId);
		glBindTexture(GL_TEXTURE_2D, textureId);
		gluBuild2DMipmaps(GL_TEXTURE_2D,
							GL_RGB,
							image->width, image->height,
							GL_RGB,
							GL_UNSIGNED_BYTE,
							image->pixels);
		return textureId;
	}

	void initRendering() 
	{
		glEnable(GL_DEPTH_TEST);
		glEnable(GL_COLOR_MATERIAL);
		glEnable(GL_LIGHTING);
		glEnable(GL_LIGHT0);
		glEnable(GL_NORMALIZE);
		glShadeModel(GL_SMOOTH);
		t3dInit();

		Image* image = loadBMP("giris.bmp");
		textureId[0] = loadTexture(image);
		delete image;
		image = loadBMP("redbrick.bmp");
		textureId[1] = loadTexture(image);
		delete image;
		image = loadBMP("Wood.bmp");
		textureId[2] = loadTexture(image);
		delete image;
		image = loadBMP("bitis.bmp");
		textureId[3] = loadTexture(image);
		delete image;
		image = loadBMP("dur.bmp");
		textureId[4] = loadTexture(image);
		delete image;
		image = loadBMP("inst.bmp");
		textureId[5] = loadTexture(image);
		delete image;
	}

	void initGame()
	{
		_karakter.theta=0;
		_karakter.xStart=0;
		_karakter.movingPoint=GL_FALSE;
		_karakter.posX=2;
		_karakter.posY=2;
		_karakter.posZ=0;
		_karakter.angle = 0.0f;

		string mapXml_s;
		char temp[256];
		ifstream mapfile;
		mapfile.open("map.xml",ifstream::in);
		while(!mapfile.eof())
		{				
			mapfile.getline(temp,256);
			mapXml_s.append(temp);
		}
		const char* mapXml;
		mapXml = mapXml_s.data();
		Map map(mapXml);
		map.RealizeMap();

		cellVector = map.getCellVector();
		objectVector = map.getObjectVector();
		questionVector = map.getQuestionVector();

		randQuestions=randomArray(questionVector.size());
		randObjects= randomArray(objectVector.size());

		for(unsigned int i=0; i<objectVector.size(); i++)
		{
			ObjLoad(const_cast<char*>(objectVector[i][0].c_str()),const_cast<char*>(objectVector[i][1].c_str()));
			objects.push_back(object);
		}
		ObjLoad("solidx.3ds","horse.bmp" );
		objects.push_back(object);

		glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
	}

	void drawScene() {
		if(game_state == START)
		{
			glPushMatrix();
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
			glLoadIdentity(); //Reset the drawing perspective

			GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

			GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
			GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};
			glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
			glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

			//Draw the strings along the sides of a square
			if(textureId[0]!=-1)
			{
				glEnable(GL_TEXTURE_2D);
				glBindTexture(GL_TEXTURE_2D, textureId[0]);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D,
					GL_TEXTURE_MIN_FILTER,
					GL_LINEAR_MIPMAP_LINEAR);
			}
			glBegin(GL_QUADS);
			glNormal3f(0.0, 0.0f, 1.0f);
			glTexCoord2f(0.0f, 0.0f);	
			glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 0.0f);
			glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 1.0f);
			glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(0.0f, 1.0f);
			glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glEnd();

			if(textureId[0]!=-1)
			{
				glDisable(GL_TEXTURE_2D);
			}

			char* STRS[7] = {" ",
				" ",
				"Egitici labirente hosgeldin! ",
				" ", 
				"Oyuna baslamak herhangi bir tusa bas. ",
				" ",
				"Oyundan cikmak icin ise ESC tusuna basabilirsin."};

			glTranslatef(0.0f,-1 / 2 *0.2f,-4.0f);
			glScalef(0.15, 0.15, 0.15);
			glColor3f(1.0f, 0.0f, 0.0f);
			for(int i = 0; i < 7; i++) {
				glPushMatrix();
				glTranslatef(0, -i, 0);
				t3dDraw3D(STRS[i], 0, 0, 0.3f);
				glPopMatrix();
			}
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();
		}
		else if(game_state == INSTRUCTIONS)
		{
			glPushMatrix();
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
			glLoadIdentity(); //Reset the drawing perspective

			//Draw the strings along the sides of a square
			if(textureId[5]!=-1)
			{
				glEnable(GL_TEXTURE_2D);
				glBindTexture(GL_TEXTURE_2D, textureId[5]);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D,
					GL_TEXTURE_MIN_FILTER,
					GL_LINEAR_MIPMAP_LINEAR);
			}
			glBegin(GL_QUADS);
			glNormal3f(0.0, 0.0f, 1.0f);
			glTexCoord2f(0.0f, 0.0f);	
			glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 0.0f);
			glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 1.0f);
			glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(0.0f, 1.0f);
			glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glEnd();

			if(textureId[5]!=-1)
			{
				glDisable(GL_TEXTURE_2D);
			}

			char* STRS[8] = {"TALIMATLAR:",
				"W, A, S, D: 4 yonde hareket ", 
				"Fare: Saga veya sola bakma ",
				"E: Objeyi alma ",
				"M ve N: Yukari ve Asagi bakma ",
				"Esc: Oyunu durdurma ",
				" ",
				"Oyuna baslamak icin herhangi bir tusa basabilirsin!"};

			glTranslatef(0.0f,3 / 2 *0.2f,-4.0f);
			glScalef(0.15, 0.15, 0.15);
			glColor3f(0.0f, 0.0f, 0.0f);
			for(int i = 0; i < 8; i++) {
				glPushMatrix();
				glTranslatef(0, -i*1.5f, 0);
				t3dDraw3D(STRS[i], 0, 0, 0.3f);
				glPopMatrix();
			}
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();
		}
		else if(game_state == PLAY)
		{
			if(toplama==6)
			{
				game_state=END;
				end_time = (int)( clock() - start ) / (double) CLOCKS_PER_SEC;
			}
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
			glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
			glLoadIdentity(); //Reset the drawing perspective

			glTranslatef(0.0f, 0.0f, -1.0f); //Move forward 15 units
			GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
			diff=( clock() - start ) / (double) CLOCKS_PER_SEC;
			cout << diff << endl;
			if(diff>x)
			{
				soruaktif = 1;
				if(diff > x+10)
				{
					x = x+30;
					if(soru!=questionVector.size()-1)
						soru++;
					else
					{
						soru=0;
					}
					soruaktif = 0;
					game_state=PLAY;
					glutPostRedisplay();
				}
				glPushMatrix();
				glTranslatef(0.0f,1 / 2 *0.2f,-0.5f);
				glScalef(0.05, 0.05, 0.05);		
				glDisable(GL_TEXTURE_2D);
				glColor3f(1.0f, 1.0f, 1.0f);
				if(soruaktif==1)
					t3dDraw3D(questionVector[randQuestions[soru]][0], 0, 0, 0.3f);		
				glEnable(GL_TEXTURE_2D);
				glColor3f(1.0f, 1.0f, 1.0f);
				glPopMatrix();

				glPushMatrix();
				glTranslatef(0.0f,4.5f / 2 *0.2f,-0.5f);
				glScalef(0.05, 0.05, 0.05);		
				glDisable(GL_TEXTURE_2D);
				glColor3f(1.0f, 1.0f, 0.0f);
				t3dDraw3D(message.data(), 0, 0, 0.3f);		
				glEnable(GL_TEXTURE_2D);
				glColor3f(1.0f, 1.0f, 1.0f);
				glPopMatrix();
			}
			else if(message.size()<0)
				message.clear();
			glPushMatrix();
			glTranslatef(0.0f,5.5f / 2 *0.2f,-0.5f);
			glScalef(0.05, 0.05, 0.05);		
			glDisable(GL_TEXTURE_2D);
			glColor3f(1.0f, 1.0f, 0.0f);
			string time = "Suren: " + convertInt((int)diff) + " sn";
			t3dDraw3D(time.data(), 0, 0, 0.3f);		
			glEnable(GL_TEXTURE_2D);
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();

			glRotatef(_karakter.angle, 1.0f, 0.0f, 0.0f);

			GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
			GLfloat lightPos[] = {0.0f, 0.0f, 10.0f, 1.0f};
			glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
			glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

			glRotatef(90,0.0f,0.0f,1.0f);
			glRotatef(90,0.0f,1.0f,0.0f);
			glRotatef(_karakter.theta,0,0,1);

			glTranslatef(-_karakter.posX,-_karakter.posY,-_karakter.posZ);		
			_oda = Cell(vector<Wall>(),Wall(36,60,-1.9,72,120,0.2,1,1,1,0,textureId[2]),0,0,0,1,0x0f);
			for(unsigned int i=0; i < cellVector.size(); i++)
			{
				_oda.AddWall(Wall(cellVector[i][0],cellVector[i][1],cellVector[i][2],cellVector[i][3],cellVector[i][4],cellVector[i][5],cellVector[i][6],cellVector[i][7],cellVector[i][8],cellVector[i][9],textureId[1]));
			}
			_oda.Draw();

			Object3d obje;
			for(unsigned int i=0; i<objectVector.size(); i++)
			{
				obje = Object3d(atof(objectVector[i][2].c_str()),atof(objectVector[i][3].c_str()),atof(objectVector[i][4].c_str()),atof(objectVector[i][5].c_str()),atof(objectVector[i][6].c_str()),atof(objectVector[i][7].c_str()));
				if(visibility==randObjects[0] && i==0){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[1] && i==1){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[2] && i==2){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[3] && i==3){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[4] && i==4){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[5] && i==5){
					object=objects[i];
					obje.Draw();
				}
			}
		}
		else if(game_state == MAP)
		{
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
			glClearColor(0.7f, 0.9f, 1.0f, 1.0f);
			glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
			glLoadIdentity(); //Reset the drawing perspective
			diff=( clock() - start ) / (double) CLOCKS_PER_SEC;
			cout << diff << endl;
			if(diff > x+10)
			{
				game_state=PLAY;		
			}
			glTranslatef(0.0f, 0.0f, -3.0f); //Move forward 15 units
			GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);

			glRotatef(90, 1.0f, 0.0f, 0.0f); //Rotate about the x-axis

			GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
			GLfloat lightPos[] = {0.0f, 0.0f, 10.0f, 1.0f};
			glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
			glLightfv(GL_LIGHT0, GL_POSITION, lightPos);

			glRotatef(90,0.0f,0.0f,1.0f);
			glRotatef(90,0.0f,1.0f,0.0f);		

			glTranslatef(-36,-60, -100);	
			_oda = Cell(vector<Wall>(),Wall(36,60,-1.9,72,120,0.2,1,1,1,0,0),0,0,0,1,0x0f);//Wall(36,60,-1.9,72,120,0.2,1,1,1,0,textureId[1]),0,0,0,1,0x0f);
			for(unsigned int i=0; i < cellVector.size(); i++)
			{
				_oda.AddWall(Wall(cellVector[i][0],cellVector[i][1],0,cellVector[i][3],cellVector[i][4],0,cellVector[i][6],cellVector[i][7],cellVector[i][8],cellVector[i][9],textureId[1]));
			}
			_oda.Draw();

			Object3d obje;
			for(unsigned int i=0; i<objectVector.size(); i++)
			{
				obje = Object3d(atof(objectVector[i][2].c_str()),atof(objectVector[i][3].c_str()),atof(objectVector[i][4].c_str()),atof(objectVector[i][5].c_str()),atof(objectVector[i][6].c_str()),atof(objectVector[i][7].c_str()));
				if(visibility==randObjects[0] && i==0){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[1] && i==1){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[2] && i==2){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[3] && i==3){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[4] && i==4){
					object=objects[i];
					obje.Draw();
				}
				if(visibility==randObjects[5] && i==5){
					object=objects[i];
					obje.Draw();
				}
			}
			obje = Object3d(_karakter.posX,_karakter.posY,0,2,2,2);
			object=objects.back();
			obje.Draw();
		}
		else if(game_state == PAUSE)
		{
			glPushMatrix();
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
			glLoadIdentity(); //Reset the drawing perspective

			GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

			GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
			GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};
			glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
			glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);

			if(textureId[4]!=-1)
			{
				glEnable(GL_TEXTURE_2D);
				glBindTexture(GL_TEXTURE_2D, textureId[4]);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D,
					GL_TEXTURE_MIN_FILTER,
					GL_LINEAR_MIPMAP_LINEAR);
			}
			glBegin(GL_QUADS);
			glNormal3f(0.0, 0.0f, 1.0f);
			glTexCoord2f(0.0f, 0.0f);	
			glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 0.0f);
			glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 1.0f);
			glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(0.0f, 1.0f);
			glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glEnd();

			if(textureId[4]!=-1)
			{
				glDisable(GL_TEXTURE_2D);
			}

			const char* STRS[8] = {" ",
				" ",
				"Oyunu durdurdun! ",
				" ", 
				"Oyuna devam etmek icin herhangi bir tusa bas. ",
				" ",
				"Baslangic ekranina donmek icin ise", 
				"ESC tusuna basabilirsin."};
			glTranslatef(0.0f,4 / 2 *0.2f,-4.0f);
			glScalef(0.15, 0.15, 0.15);
			glColor3f(1.0f, 0.0f, 0.0f);
			for(int i = 0; i < 8; i++) {
				glPushMatrix();
				glTranslatef(0, -i, 0);
				t3dDraw3D(STRS[i], 0, 0, 0.3f);
				glPopMatrix();
			}
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();
		}
		else if(game_state == END)
		{
			glPushMatrix();
			glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

			glMatrixMode(GL_MODELVIEW); //Switch to the drawing perspective
			glLoadIdentity(); //Reset the drawing perspective

			GLfloat ambientColor[] = {0.4f, 0.4f, 0.4f, 1.0f};
			glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientColor);

			GLfloat lightColor0[] = {0.6f, 0.6f, 0.6f, 1.0f};
			GLfloat lightPos0[] = {-0.5f, 0.5f, 1.0f, 0.0f};
			glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor0);
			glLightfv(GL_LIGHT0, GL_POSITION, lightPos0);


			//Draw the strings along the sides of a square
			if(textureId[3]!=-1)
			{
				glEnable(GL_TEXTURE_2D);
				glBindTexture(GL_TEXTURE_2D, textureId[3]);
				glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
				glTexParameteri(GL_TEXTURE_2D,
					GL_TEXTURE_MIN_FILTER,
					GL_LINEAR_MIPMAP_LINEAR);
			}
			glBegin(GL_QUADS);
			glNormal3f(0.0, 0.0f, 1.0f);
			glTexCoord2f(0.0f, 0.0f);	
			glVertex3f(-UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 0.0f);
			glVertex3f(UNIT_SIZE * 2.9, -UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(1.0f, 1.0f);
			glVertex3f(UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glTexCoord2f(0.0f, 1.0f);
			glVertex3f(-UNIT_SIZE * 2.9, UNIT_SIZE * 2.1, -5.0f);
			glEnd();

			if(textureId[3]!=-1)
			{
				glDisable(GL_TEXTURE_2D);
			}
			string score = "Suren: " + convertInt(end_time) + " saniye" ;
			const char* STRS[9] = {" ",
				" ",
				" ",
				" ", 
				"Tebrikler! Oyunu basariyla tamamladin.",
				score.data(),
				" ",
				"Baslangic ekranina donmek herhangi bir tusa bas. ",
				"Oyundan cikmak icin ise ESC tusuna basabilirsin."};
			glTranslatef(0.0f,-5 / 2 *0.2f,-4.0f);
			glScalef(0.10, 0.10, 0.10);
			glColor3f(1.0f, 1.0f,1.0f);
			for(int i = 0; i < 9; i++) {
				glPushMatrix();
				glTranslatef(0, -i*1.2, 0);
				t3dDraw3D(STRS[i], 0, 0, 0.3f);
				glPopMatrix();
			}
			glColor3f(1.0f, 1.0f, 1.0f);
			glPopMatrix();
		}
		glutSwapBuffers();
	}
}
